package ysq.xyg.controller;

import com.github.pagehelper.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ysq.weixin.client.WxApiClient;
import ysq.weixin.client.WxMemoryCacheClient;
import ysq.weixin.model.info.OAuthAccessToken;
import ysq.weixin.model.info.OAuthScope;
import ysq.weixin.model.info.User;
import ysq.weixin.util.WxUrlUtil;
import ysq.xyg.model.Member;
import ysq.xyg.model.info.WxAccountInfo;
import ysq.xyg.service.BaseConfigService;
import ysq.xyg.service.MemberService;
import ysq.xyg.util.BaseConstant;
import ysq.xyg.util.BaseUtil;
import ysq.xyg.util.DateUtil;
import ysq.xyg.util.ProProperties;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

/**
 * Created by Administrator on 2017/6/23 0023.
 */
@Controller
@RequestMapping("/weiXin")
public class WeXinController extends BaseController {
    private static final Logger log= LoggerFactory.getLogger(WeXinController.class);

    @Autowired
    private MemberService memberService;

    /**
     * oauth2.0跳转入库
     * state:1.首页,2,品牌页面，3、商品页面
     * */
    @RequestMapping("/oauth/{state}")
    public ModelAndView oauth(HttpServletResponse response, HttpServletRequest request, @PathVariable String state) throws IOException {
        String oauthType = request.getParameter("oauthType");
        String params = request.getParameter("params");
        String path = request.getParameter("path");
        String pathParams = request.getParameter("pathParams");
        String scope= OAuthScope.Base.toString();
        if(OAuthScope.Userinfo.toString().equals(oauthType)){
            scope= OAuthScope.Userinfo.toString();
        }
        WxAccountInfo wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();//获取缓存中的唯一账号
        String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams,scope, state);
        return new ModelAndView("redirect:" + url);
    }

    /**
     * 获取openid 并跳转
     * */
    @RequestMapping("/acceptOpenid")
    public ModelAndView acceptOpenid(HttpServletResponse response, HttpServletRequest request) throws IOException {
        String code = request.getParameter("code");
        // 获取到的state是模式页面组合，模式由一个字符，1表示base,2表示userinfo,其他为页面标识符
        String scopeState = request.getParameter("state");
        String scope= scopeState.substring(0,1);
        String state = scopeState.substring(1,scopeState.length());
        String params = request.getParameter("params");
        String path = request.getParameter("path");
        String pathParams = request.getParameter("pathParams");
        if("null".equals(params)){
            params="";
        }
        log.info("scopeState is "+scopeState+"code is "+code+";state is "+state+";scope is "+scope+";params is "+params);
        ModelAndView modelAndView=null;
        try {
            // 获取缓存中的唯一账号
            WxAccountInfo wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();
            OAuthAccessToken oAuthAccessToken = WxApiClient.getOAuthOpenId(wxAccountInfo, code);
            log.info("openid is "+oAuthAccessToken.getOpenid());
            if (StringUtils.isEmpty(oAuthAccessToken.getOpenid())) {
                //跳转到oauth2.0的url
                String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams, OAuthScope.Base.toString(), state);
                modelAndView =  new ModelAndView("redirect:" + url);
            }else{
                //判断当前用户是否已经保存到数据库

                Member member = createUser(oAuthAccessToken,scope);
                if (member != null) {
                    String url="";
                    if(StringUtil.isNotEmpty(path)&&!("null".equalsIgnoreCase(path))){
                        url=path+"?memberId="+member.getId();
                        if(StringUtil.isNotEmpty(pathParams)&&!("null".equalsIgnoreCase(pathParams))){
                            String[] t=pathParams.split(",");
                            for (String c:t){
                                String[] k=c.split("\\*");
                                url+="&"+k[0]+"="+k[1];
                            }
                        }
                    }

                    modelAndView = acceptView(params,member,url);
                } else {
                    //跳转到oauth2.0的url
                    String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams, OAuthScope.Userinfo.toString(), state);
                    modelAndView =  new ModelAndView("redirect:" + url);
                }
                return modelAndView;
            }
        } catch (Exception e) {
            //跳转错误页面
            e.printStackTrace();
        }
        return modelAndView;
    }
    protected ModelAndView acceptView(String params, Member member, String url){
        ModelAndView modelAndView=null;
        if(StringUtil.isNotEmpty(url)) {
            //参数页面
            modelAndView = new ModelAndView("redirect:"+url);
        }else{
            //默认页面
            modelAndView = new ModelAndView("redirect:"+ ProProperties.getInstance().getWxOauthRredirectIndexURL(member.getId()));
        }
        return  modelAndView;
    }

    /**
     * 创建本地用户
     * @return
     */
    protected Member createUser(OAuthAccessToken oAuthAccessToken, String scope){
        Member member=memberService.selectEntityByOpenid(oAuthAccessToken.getOpenid());
        if(member == null){
            // 用户不存在
            if(BaseConstant.OAUTH_USERINFO.equals(scope)){
                //Oauth为获取用户信息模式
                User user= WxApiClient.getOAuthUserInfo(oAuthAccessToken);
                if(user!=null){
                    //将用户信息插入数据库
                    member=new Member();
                    int memberNum = memberService.selectMaxId();
                    if (memberNum < BaseConstant.MEMBER_MIN_DEFAULT_ID) {
                        memberNum = BaseConstant.MEMBER_MIN_DEFAULT_ID;
                    } else {
                        memberNum = memberNum + 1;
                    }
                    String cardNo= DateUtil.DateToStr(new Date(),"yyyyMMdd");
                    for(int i=0;i<(5-(memberNum+"").length());i++){
                     cardNo+="0";
                    }
                    cardNo+=(memberNum+"");
                    member.setMemberNum(memberNum);
                    member.setId(BaseUtil.uId());
                    member.setCardNo("A"+cardNo);
                    member.setOpenid(user.getOpenid());
                    member.setHeadImage(user.getHeadlogo());
                    member.setNickName(BaseUtil.encodeBase64String(user.getNickname()));
                    member.setCreateTime(new Date());
                    //级别：1、普通会员，2、Vip会员
                    member.setGrade("1");
                    member.setUnionid(user.getUnionid());
                    member.setMoney(0.0);
                    member.setIntegral(0);
                    int ids=memberService.insert(member);
                    if(ids>0){
                        return member;
                    }
                }
            }
            return null;
        }else{
            //用户存在
            return member;
        }
    }


    //从输入流读取post参数
    protected String readStreamParameter(ServletInputStream in){
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader=null;
        try{
            reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
            String line=null;
            while((line = reader.readLine())!=null){
                buffer.append(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(null!=reader){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return buffer.toString();
    }
}
